cmake_minimum_required(VERSION 3.16)
set(CMAKE_TOOLCHAIN_FILE "E:/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")

project(CworkTest)
set(CMAKE_CXX_STANDARD 17)
if(MSVC)
    add_compile_options(/source-charset:utf-8 /execution-charset:utf-8)
else()
    add_compile_options(-finput-charset=UTF-8 -fexec-charset=UTF-8)
endif()

set(ONNXRUNTIME_DIR "E:/onnxruntime-win-x64-1.22.0")
set(ONNXRUNTIME_INCLUDE_DIR "${ONNXRUNTIME_DIR}/include")
set(ONNXRUNTIME_LIBRARY "${ONNXRUNTIME_DIR}/lib/onnxruntime.lib")
set(ONNXRUNTIME_DLL "${ONNXRUNTIME_DIR}/lib/onnxruntime.dll")

# find_package(OpenCV REQUIRED COMPONENTS core imgproc highgui ximgproc photo)

message(STATUS "OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}")
message(STATUS "OpenCV_LIBS: ${OpenCV_LIBS}")

find_package(OpenMP REQUIRED)
find_package(SQLite3 REQUIRED)
find_package(hiredis CONFIG REQUIRED)
find_package(redis++ CONFIG REQUIRED)
# 告诉 CMake 使用 vcpkg
find_package(Crow CONFIG REQUIRED)


# ---------------------------- CURL 配置 ----------------------------
set(CURL_INCLUDE_DIR "E:/vcpkg/installed/x64-windows/include")
set(CURL_LIBRARY "E:/vcpkg/installed/x64-windows/lib/libcurl.lib")
include_directories(${CURL_INCLUDE_DIR})
link_libraries(${CURL_LIBRARY})
if (EXISTS ${CURL_INCLUDE_DIR}/curl/curl.h)
    message(STATUS "✅ Found curl.h in ${CURL_INCLUDE_DIR}")
else()
    message(FATAL_ERROR "❌ curl.h not found in ${CURL_INCLUDE_DIR}")
endif()
find_package(CURL REQUIRED) #如果你使用了 vcpkg 安装的 curl，那么推荐直接使用：

# ---------------- gRPC 配置 ----------------
find_package(Protobuf CONFIG REQUIRED)
find_package(gRPC CONFIG REQUIRED)
find_package(ZLIB REQUIRED)   # vcpkg 会帮你找到

message(STATUS "Protobuf_INCLUDE_DIRS: ${Protobuf_INCLUDE_DIRS}")
message(STATUS "gRPC_LIBRARIES: ${gRPC_LIBRARIES}")
message(STATUS "Protobuf targets: ${Protobuf_LIBRARIES}")

# ---------------- Proto 文件配置 ----------------
set(PROTO_FILE "srcutils/CgRPC/user.proto")
set(PROTO_GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/CgRPC_proto")
file(MAKE_DIRECTORY ${PROTO_GEN_DIR})
## MySQL数据库的配置操作
# find_package(mysql-connector-cpp CONFIG REQUIRED)

# 自定义命令生成 protobuf + gRPC 文件
add_custom_command(
        OUTPUT ${PROTO_GEN_DIR}/user.pb.cc ${PROTO_GEN_DIR}/user.pb.h
        ${PROTO_GEN_DIR}/user.grpc.pb.cc ${PROTO_GEN_DIR}/user.grpc.pb.h
        COMMAND ${Protobuf_PROTOC_EXECUTABLE}
        ARGS --grpc_out=${PROTO_GEN_DIR}
        --cpp_out=${PROTO_GEN_DIR}
        --plugin=protoc-gen-grpc=${gRPC_CPP_PLUGIN_EXECUTABLE}
        -I ${CMAKE_CURRENT_SOURCE_DIR}
        ${PROTO_FILE}
        DEPENDS ${PROTO_FILE}
        COMMENT "Generating gRPC / protobuf files from ${PROTO_FILE}"
)

# 保存生成的文件变量
set(PROTO_SRCS ${PROTO_GEN_DIR}/user.pb.cc ${PROTO_GEN_DIR}/user.grpc.pb.cc)
set(PROTO_HDRS ${PROTO_GEN_DIR}/user.pb.h ${PROTO_GEN_DIR}/user.grpc.pb.h)


function(configure_target target_name)
    add_executable(${target_name} ${ARGN})
    target_include_directories(${target_name} PRIVATE
            ${OpenCV_INCLUDE_DIRS}
            ${ONNXRUNTIME_INCLUDE_DIR}
            ${ZLIB_INCLUDE_DIR}
            #${Qt5Widgets_INCLUDE_DIRS} # 如果用Qt
    )
    target_link_libraries(${target_name} PRIVATE
            ${OpenCV_LIBS}
            ${ZLIB_LIBRARIES}
            ${ONNXRUNTIME_LIBRARY}
            #Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Sql  # 如果用Qt
    )
    target_link_libraries(${target_name} PRIVATE gRPC::grpc++ gRPC::grpc ZLIB::ZLIB ${Protobuf_LIBRARIES})
    message(STATUS "MySQL Connector C++ include dir: ${unofficial-mysql-connector-cpp_INCLUDE_DIRS}")
    # 链接sqlite3库
    target_link_libraries(${target_name} PRIVATE SQLite::SQLite3)
    # 使用redis
    target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
    target_link_libraries(${target_name} PRIVATE redis++::redis++ hiredis::hiredis)
    target_link_libraries(${target_name} PRIVATE Crow::Crow)


    target_include_directories(${target_name} PRIVATE ${CURL_INCLUDE_DIRS})
    target_link_libraries(${target_name} PRIVATE CURL::libcurl)
    # ✅ OpenMP 链接添加到这里
    if(OpenMP_CXX_FOUND)
        target_link_libraries(${target_name} PRIVATE OpenMP::OpenMP_CXX)
    endif()

    target_compile_features(${target_name} PRIVATE cxx_std_17)
    add_custom_command(TARGET ${target_name} POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different
            "${ONNXRUNTIME_DLL}"
            "$<TARGET_FILE_DIR:${target_name}>"
    )
    add_custom_command(
         OUTPUT ${PROTO_GEN_DIR}/user.pb.cc ${PROTO_GEN_DIR}/user.pb.h
                ${PROTO_GEN_DIR}/user.grpc.pb.cc ${PROTO_GEN_DIR}/user.grpc.pb.h
         COMMAND ${Protobuf_PROTOC_EXECUTABLE}
         ARGS --grpc_out=${PROTO_GEN_DIR}
              --cpp_out=${PROTO_GEN_DIR}
              --plugin=protoc-gen-grpc=${gRPC_CPP_PLUGIN_EXECUTABLE}
              -I ${CMAKE_CURRENT_SOURCE_DIR}
              ${PROTO_FILE}
         DEPENDS ${PROTO_FILE}
    )

endfunction()


# ---------------- 构建函数 ----------------
function(configure_target_grpc target_name source_file)
    add_executable(${target_name}
            ${source_file}   # server.cpp / client.cpp
            ${PROTO_SRCS}    # protobuf 生成的源文件
    )

    # 包含目录
    target_include_directories(${target_name} PRIVATE
            ${OpenCV_INCLUDE_DIRS}
            ${ONNXRUNTIME_INCLUDE_DIR}
            ${ZLIB_INCLUDE_DIR}
            ${PROTO_GEN_DIR}  # protobuf 生成的头文件目录
    )

    # 链接库
    target_link_libraries(${target_name} PRIVATE
            ${OpenCV_LIBS}
            ${ZLIB_LIBRARIES}
            ${ONNXRUNTIME_LIBRARY}
            gRPC::grpc++ gRPC::grpc ${Protobuf_LIBRARIES}
            SQLite::SQLite3
            redis++::redis++ hiredis::hiredis
            Crow::Crow
            CURL::libcurl
    )

    if(OpenMP_CXX_FOUND)
        target_link_libraries(${target_name} PRIVATE OpenMP::OpenMP_CXX)
    endif()

    target_compile_features(${target_name} PRIVATE cxx_std_17)

    # 拷贝 ONNX Runtime DLL
    add_custom_command(TARGET ${target_name} POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy_if_different
            "${ONNXRUNTIME_DLL}"
            "$<TARGET_FILE_DIR:${target_name}>"
    )
endfunction()


##########################################CPP17文件夹的开始##############################################################
configure_target(SQLConnect oldsrc/CPP/CPP17/D19PoolSQL/SQLConnect.cpp)
configure_target(HttpClientTest
        srcutils/HttpClient/main.cpp
        srcutils/HttpClient/HttpClient.h
        srcutils/HttpClient/HttpClient.cpp
)
# 配置redis的案例
configure_target(RedisClient
        srcutils/CRedis/main.cpp
        srcutils/CRedis/RedisClient.h
        srcutils/CRedis/RedisClient.cpp
)

# 实现SQLite的相关操作
configure_target(SQLiteDB
        srcutils/CSQLite/main.cpp
        srcutils/CSQLite/SQLiteDB.h
        srcutils/CSQLite/SQLiteDB.cpp)

# TCPService的案例
configure_target(runServerMain
        srcutils/CPPSocket/runServerMain.cpp
        srcutils/CPPSocket/TcpSocket.h
        srcutils/CPPSocket/TcpSocket.cpp)

configure_target(runClientMain
        srcutils/CPPSocket/runClientMain.cpp
        srcutils/CPPSocket/TcpSocket.h
        srcutils/CPPSocket/TcpSocket.cpp)

configure_target(CrowCase1
        srcutils/CPPCrow/CrowCase1.cpp)

configure_target(CrowCase2
        srcutils/CPPCrow/mian.cpp
        srcutils/CPPCrow/MyController.h)

configure_target(ThreadPoolTest
        srcutils/CPPCASE/ThreadPool/ThreadPool.cpp
        srcutils/CPPCASE/ThreadPool/ThreadPool.h
        srcutils/CPPCASE/ThreadPool/main.cpp)

configure_target(gRPCD1
        srcutils/CgRPC/server/server.cpp
        srcutils/CgRPC/user.proto
        srcutils/CgRPC/client/client.cpp)

configure_target_grpc(gRPCServer srcutils/CgRPC/server/server.cpp)
configure_target_grpc(gRPCClient srcutils/CgRPC/client/client.cpp)


configure_target(MySQLTest
        srcutils/CMySQL/main.cpp
        srcutils/CMySQL/MySQLDB.h
        srcutils/CMySQL/MySQLDB.cpp)
##########################################CPP17文件夹的结束##############################################################

#########################################################MianShiYaShuaTI-Start#########################################################
#########################################################MianShiYaShuaTI-End###########################################################